/* 
 * LoginController.java
 * Copyright (c) Faculdade Anhanguera de Anápolis.
 * Tecnologia em Análise e Desenvolvimento de Sistemas.
 * Projeto Multidisciplinar de Autoaprendizagem.
 *
 * Este software é confidencial e propriedade da Faculdade Anhanguera de Anápolis.
 * Não é permitida sua distribuição ou divulgação do seu conteúdo sem expressa autorização da Faculdade Anhanguera de Anápolis.
 * Este arquivo contém informações proprietárias.
 */
package br.com.pma.chamatec.controller;

import java.io.IOException;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;

import br.com.pma.chamatec.business.IUsuarioBO;
import br.com.pma.chamatec.exception.ChamatecExceptionCode;
import br.com.pma.chamatec.exception.ChamatecNegocioException;
import br.com.pma.entity.Usuario;

/**
 * Controlador de login dos usuários.
 *
 * @author Ludemeula Fernandes de Sá
 */
@ManagedBean
@SessionScoped
public class LoginController extends AbstractController {
	private static final long serialVersionUID = 7555443390457017707L;

	@ManagedProperty(value = "#{authenticationManager}")
	private AuthenticationManager authenticationManager = null;
	private String login;
	private String senha;

	@Inject
	private IUsuarioBO usuarioBO;

	@Inject
	private Usuario usuario;

	/**
	 * Realiza a autenticação do usuário.
	 * 
	 */
	public String login() {
		try {
            login(getLogin(), getSenha());
            this.usuario.setLogin(getLogin());
            this.usuario = usuarioBO.recuperarPorLogin(usuario);
		} catch (ChamatecNegocioException e) {
			addFacesMessage(e.getMessage(), FacesMessage.SEVERITY_ERROR);
			return null;
        } catch (AuthenticationException e) {
        	addFacesMessage(ChamatecExceptionCode.ERRO_LOGIN, FacesMessage.SEVERITY_ERROR);
            return null;
		} catch (Exception e) {
			montaMensagemGenerica(e);
			return null;
		}

		return "index.jsf?faces-redirect=true";
	}

	/**
	 * Realiza autenticação do usário utilizando o spring.
	 * 
	 * @param usuario
	 * @param senha
	 * @throws ChamatecNegocioException
	 */
	private void login(String usuario, String senha) throws ChamatecNegocioException {
		if (usuario != null && !usuario.equals("") && senha != null && !senha.equals("")) {
			Authentication request = new UsernamePasswordAuthenticationToken(usuario, senha);
			Authentication result = authenticationManager.authenticate(request);
			SecurityContextHolder.getContext().setAuthentication(result);
		} else {
			throw new ChamatecNegocioException(ChamatecExceptionCode.ME_002);
		}
	}

	/**
	 * Efetua o logout do sistema.
	 * 
	 * @return
	 */
	public String logout() {
		SecurityContext sc = SecurityContextHolder.getContext();
        Authentication authentication = sc.getAuthentication();  
		final HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();  

        SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();      
        logoutHandler.setInvalidateHttpSession(true);  
        logoutHandler.logout(request, null, authentication);
        return "/login.jsf";
	}

	/**
	 * Verifica se o usuário está logado e caso não esteja redireciona para a página de login.
	 * 
	 */
	public void verificaLogin() {
		SecurityContext sc = SecurityContextHolder.getContext();  
		Authentication authentication = sc.getAuthentication();
		if (authentication.getPrincipal() == null || authentication.getPrincipal().toString().equals("anonymousUser")) { 
			try {
				facesContext.getExternalContext().redirect("login.jsf");
				facesContext.responseComplete();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/********************************************* Getters e Setters *****************************************************/
	/**
	 * @return the authenticationManager
	 */
	public AuthenticationManager getAuthenticationManager() {
		return authenticationManager;
	}

	/**
	 * @param authenticationManager the authenticationManager to set
	 */
	public void setAuthenticationManager(AuthenticationManager authenticationManager) {
		this.authenticationManager = authenticationManager;
	}

	/**
	 * @return the login
	 */
	public String getLogin() {
		return login;
	}

	/**
	 * @param login the login to set
	 */
	public void setLogin(String login) {
		this.login = login;
	}

	/**
	 * @return the senha
	 */
	public String getSenha() {
		return senha;
	}

	/**
	 * @param senha the senha to set
	 */
	public void setSenha(String senha) {
		this.senha = senha;
	}

	/**
	 * @return the usuario
	 */
	public Usuario getUsuario() {
		return usuario;
	}

	/**
	 * @param usuario the usuario to set
	 */
	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}
}